package com.starmark.gateway.project.provider.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.starmark.core.framework.base.AbstractBaseService;
import com.starmark.core.framework.base.BaseTree;
import com.starmark.core.framework.constants.SysCommonConstant;
import com.starmark.core.framework.util.BeanMapper;
import com.starmark.core.framework.util.RedisUtils;
import com.starmark.gateway.project.provider.entity.GatewayApp;
import com.starmark.gateway.project.provider.entity.GatewayAppMachine;
import com.starmark.gateway.project.provider.mapper.GatewayAppMapper;
import com.starmark.gateway.project.provider.service.IGatewayAppMachineService;
import com.starmark.gateway.project.provider.service.IGatewayAppService;
import com.starmark.gateway.project.provider.service.IGatewayRouteService;
import com.starmark.gateway.project.provider.vo.GatewayAppMachineVo;
import com.starmark.gateway.project.provider.vo.GatewayAppVo;
import cn.hutool.core.util.StrUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 网关应用 服务实现类
 * </p>
 *
 * @author starmark
 * @since 2020-01-24
 */
@Service
public class GatewayAppServiceImpl extends AbstractBaseService<GatewayAppMapper, GatewayApp> implements IGatewayAppService {

    private static final String STARMARK_GATEWAY_APPS = "starmark:gateway:apps:";
    @Autowired
    private IGatewayAppMachineService gatewayAppMachineService;
    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    @Lazy
    private IGatewayRouteService gatewayRouteService;

    @Override
    public void buildPageSearch(Map<String, Object> params, QueryWrapper<GatewayApp> eWrapper) {
        if (params.get("keyword") != null && StrUtil.isNotEmpty(params.get("keyword") + "")) {
            eWrapper.like("name", params.get("keyword") + "");
        }
        //查询工程ID
        eWrapper.eq("project_code", params.get("projectCode") + "");


    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String addApp(GatewayAppVo gatewayAppVo) {
        GatewayApp gatewayApp = BeanMapper.map(gatewayAppVo, GatewayApp.class);
        this.save(gatewayApp);
        List<GatewayAppMachineVo> machineList = gatewayAppVo.getMachineList();
        machineList.forEach(machineVo -> {
            GatewayAppMachine machine = BeanMapper.map(machineVo, GatewayAppMachine.class);
            machine.setAppId(gatewayApp.getId());
            gatewayAppMachineService.save(machine);
        });
        gatewayAppVo.setId(gatewayApp.getId());
        //设置缓存
        gatewayRouteService.createGatewayRoute(gatewayAppVo);
        redisUtils.set(STARMARK_GATEWAY_APPS + gatewayApp.getProjectCode() + ":" + gatewayApp.getId(),
                JSONObject.toJSONString(gatewayAppVo));
        return gatewayApp.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateApp(GatewayAppVo gatewayAppVo) {
        Assert.hasText(gatewayAppVo.getId(), "应用ID不允许为空");
        GatewayApp gatewayApp = BeanMapper.map(gatewayAppVo, GatewayApp.class);
        this.updateById(gatewayApp);
        //先删除子数据
        gatewayAppMachineService.deleteMachinesByAppId(gatewayApp.getId());
        List<GatewayAppMachineVo> machineList = gatewayAppVo.getMachineList();
        machineList.forEach(machineVo -> {
            GatewayAppMachine machine = BeanMapper.map(machineVo, GatewayAppMachine.class);
            machine.setAppId(gatewayApp.getId());
            gatewayAppMachineService.save(machine);
        });
        gatewayRouteService.deleteRouteByAppId(gatewayApp.getId());
        gatewayRouteService.createGatewayRoute(gatewayAppVo);
        redisUtils.set(STARMARK_GATEWAY_APPS + gatewayApp.getProjectCode() + ":" + gatewayApp.getId(),
                JSONObject.toJSONString(gatewayAppVo));
    }

    @Override
    public GatewayAppVo getApp(String id) {
        GatewayApp gatewayApp = this.getById(id);
        GatewayAppVo gatewayAppVo = BeanMapper.map(gatewayApp, GatewayAppVo.class);
        List<GatewayAppMachine> machines = gatewayAppMachineService.getMachineListByAppId(id);
        gatewayAppVo.setMachineList(BeanMapper.mapList(machines, GatewayAppMachineVo.class));
        return gatewayAppVo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(String id) {
        Assert.hasText(id, "应用ID不允许为空");
        GatewayApp gatewayApp = this.getById(id);
        Assert.notNull(gatewayApp, "应用不存在" + id);
        //先删除子数据
        gatewayAppMachineService.deleteMachinesByAppId(id);
        gatewayRouteService.deleteRouteByAppId(id);
        this.removeById(id);
        //设置缓存
        redisUtils.del(STARMARK_GATEWAY_APPS + gatewayApp.getProjectCode() + ":" + gatewayApp.getId() + "*");

    }


    @Override
    public List<BaseTree> findBaseTrees(String projectCode) {
        QueryWrapper<GatewayApp> eWrapper = new QueryWrapper();
        //查询工程ID
        eWrapper.eq("project_code", projectCode);
        List<GatewayApp> apps = this.list(eWrapper);
        return apps.stream().map(this::buildTree).collect(Collectors.toList());
    }

    private BaseTree buildTree(GatewayApp gatewayApp) {
        BaseTree baseTree = new BaseTree();
        baseTree.setId(gatewayApp.getId());
        baseTree.setName(gatewayApp.getAppName());
        baseTree.setParentId(SysCommonConstant.ROOT);
        return baseTree;
    }

    @Override
    public void overload() {
        List<GatewayApp> apps=this.list();
        apps.forEach(app->{
            GatewayAppVo appVo=this.getApp(app.getId());
            gatewayRouteService.createGatewayRoute(appVo);
        });
    }

}
